package org.neogenesis.web.controller;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Map;

import java.util.List;

import java.util.ResourceBundle;
import java.util.logging.Level;

import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.validator.ValidatorException;

import javax.inject.Inject;
import javax.inject.Named;

import org.apache.log4j.Logger;

import org.neogenesis.web.Configurations;
import org.neogenesis.web.dao.ExperimentDAO;
import org.neogenesis.web.dao.PlatformDAO;
import org.neogenesis.web.dao.SampleDAO;
import org.neogenesis.web.dao.SampleTypeDAO;
import org.neogenesis.web.exception.EccezioneSampleNoNPresenti;

import org.neogenesis.web.model.Experiment;
import org.neogenesis.web.model.Platform;
import org.neogenesis.web.model.Sample;
import org.neogenesis.web.model.SampleType;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.event.FlowEvent;

/**
 * @author Nancy
 * 
 */
@Named
@SessionScoped
public class ExperimentController implements Serializable {

	private Experiment experiment;

	private Platform platform;

	private List<Sample> samples;


	private Sample sample;
	@Inject
	private ExperimentDAO experimentDAO;
	@Inject
	private PlatformDAO platformDAO;

	@Inject
	private SampleDAO sampleDAO;

	@Inject
	private SampleTypeDAO sampleTypeDAO;
	


	private FacesContext context = FacesContext.getCurrentInstance();


	private ResourceBundle bundle = context.getApplication().getResourceBundle(
			context, "bundle");

	private String filePath;

	private static Logger logger = Logger.getLogger(ExperimentController.class
			.getName());

	public ExperimentController() {
		// TODO Auto-generated constructor stub

	}

	@PostConstruct
	protected void init() {
		experiment = new Experiment();
		samples = new ArrayList<Sample>();
		sample = new Sample();
		platform = new Platform();

	}

	public void setExperiment(Experiment experiment) {
		this.experiment = experiment;
	}

	public String onFlowProcess(FlowEvent event) {
		logger.info("Current wizard step:" + event.getOldStep());
		if(experiment.getSeriesIid()==null || experiment.getSeriesIid().length()==0){
				
		        return event.getOldStep();
				
				}
		logger.info("Next step:" + event.getNewStep());
		return event.getNewStep();

	}

	public Experiment getExperiment() {
		return experiment;
	}

	public Sample getSample() {
		return sample;
	}

	public void setSample(Sample sample) {
		this.sample = sample;
	}

	public void setSampleWithPlatSelected() {
		sample.setPlatformId(platform.getId());
		
	}

	public List<SampleType> getSampleTypes() {
		List<SampleType> types = sampleTypeDAO.findAll();
		return types;
	}

	public List<Platform> getPlatformList() {
		List<Platform> list = platformDAO.findAll();
		return list;
	}

	public Platform getPlatform() {
		return platform;
	}

	public void setPlatform(Platform platform) {
		this.platform = platform;
	}

	public void addSampleToList() {

		sample.setObservationFile(filePath);
		samples.add(sample);
		sample = new Sample();
		filePath = "";

	}


	public void deleteToList() {

		samples.remove(sample);
	}

	public List<Experiment> getExperimentList() {
		List<Experiment> list = experimentDAO.findAll();
		return list;
	}

	public List<Sample> samplesOfExperiment() {
		List<Sample> s = experimentDAO.sampleOfExperiment(experiment);
		return s;
	}

	public String deleteExp() {

		experimentDAO.remove(experiment);
		return "backToDeleteList";
	}

	public void addInfo() {
		FacesContext.getCurrentInstance().addMessage(
				null,
				new FacesMessage(FacesMessage.SEVERITY_INFO,
						"Sample info message", "PrimeFaces rocks!"));
	}

	public void displayLocation(ActionEvent e) {

		System.out.println("ooooooooooooooooooooooooooooooooooooo");
		FacesMessage msg = new FacesMessage("Selected", "Platform:"
				+ platform.getAccessionName());
		
		FacesContext.getCurrentInstance().addMessage(null, msg);
	}
	
	

	public void validateName(FacesContext context, UIComponent component,
			Object value) throws ValidatorException {
		String name = (String) value;

		if (name == null) {
			FacesMessage msg = new FacesMessage(
					FacesMessage.SEVERITY_ERROR,
					bundle.getString("CreatePlatformRequiredMessage_accessionName"),
					bundle.getString("CreatePlatformInsertValid_accessionName"));
			throw new ValidatorException(msg);
		}

		if (name.length() == 0) {
			FacesMessage msg = new FacesMessage(
					FacesMessage.SEVERITY_ERROR,
					bundle.getString("CreatePlatformRequiredMessage_accessionName"),
					bundle.getString("CreatePlatformInsertValid_accessionName"));
			throw new ValidatorException(msg);
		}

	}

	public void handleFileUpload(FileUploadEvent event) {
		
		if (sample == null){
			FacesMessage msg = new FacesMessage(
					FacesMessage.SEVERITY_ERROR,
					bundle.getString("CreatePlatformRequiredMessage_accessionName"),
					bundle.getString("CreatePlatformInsertValid_accessionName"));
			
			return;
		}
		
		FacesMessage msg = new FacesMessage("Succesful", event.getFile()
				.getFileName() + " is uploaded.");
		FacesContext.getCurrentInstance().addMessage(null, msg);
		byte[] content = event.getFile().getContents();
		String fileName = event.getFile().getFileName();

		try {
			filePath = saveFile(fileName, content);
			System.out.println(sample);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	private String saveFile(String name, byte[] content)
			throws FileNotFoundException, IOException {

		String webAppPath = FacesContext.getCurrentInstance()
				.getExternalContext().getRealPath("/");

		String filePath = webAppPath + Configurations.uploadPath + name;
		FileOutputStream fos = new FileOutputStream(filePath);
		fos.write(content);
		fos.flush();
		fos.close();
		return filePath;
	}

	private void createSamples() throws EccezioneSampleNoNPresenti {

		Sample s;
		// l'esperimento non può essere creato xkè non ha campioni
		
		if (samples.size() == 0){
		
			FacesMessage msg = new FacesMessage(
					FacesMessage.SEVERITY_ERROR,
					bundle.getString("CreatePlatformRequiredMessage_accessionName"),
					bundle.getString("CreatePlatformInsertValid_accessionName"));
					throw new ValidatorException(msg);}

		for (int i = 0; i < samples.size(); i++) {
			s = samples.get(i);
			s.setExperiment(experiment);

			try {
				sampleDAO.createSampleFile(s,s.getObservationFile());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	public String createExperiment() {

		experimentDAO.create(experiment);

		try {
			createSamples();
		} catch (EccezioneSampleNoNPresenti e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		experimentDAO.mergeListSample(experiment, samples);
		return "";
	}

	public List<Sample> getSamples() {
		return samples;
	}

	public void setSamples(List<Sample> samples) {
		this.samples = samples;
	}
}
